import 'package:dio/dio.dart';

import 'package:ysy_flutter_mvvm_yuanxuan/api/HttpConfig.dart';
import 'package:ysy_flutter_mvvm_yuanxuan/api/HttpUtil.dart';
import 'package:ysy_flutter_mvvm_yuanxuan/base/BaseVMProvide.dart';
import 'package:ysy_flutter_mvvm_yuanxuan/base/LoadDialog.dart';
import 'package:ysy_flutter_mvvm_yuanxuan/helper/ViewHelper.dart';
import '../bean/base/BaseBean.dart';

typedef RequestResult<T> = void Function(T t);

typedef RequestDone  = void Function();

typedef RequestResultErr = void Function(BaseBean t);

class BaseModel extends BaseVMProvide {

  //判断code 是否 200
  void onNetWorkVerdict(
      {required Future future,
      required RequestResult result,
      RequestResultErr? err,
      RequestDone? done,
      bool isDialog = true}) async {
      onAsyncNetWork(future: future, result: (data){
          if (judgeResultCode(data)) {
            result(data);
          } else {
            var baseBean = BaseBean.fromJson(data);
            if (err != null){
              err(baseBean);
            }else{
              showCenterToast(errTransformTip(baseBean.code));
            }
          }
      },err: err,done:done,isDialog: isDialog);
  }

  //判断code 是否 200 且 data 是否不为空
  void onNetWorkVerdictAndData(
      {required Future future,
        required RequestResult result,
        RequestResultErr? err,
        RequestDone? done,
        bool isDialog = true}) async {
    onAsyncNetWork(future: future, result: (data){
      if (judgeResultCodeAndData(data)) {
         result(data);
      } else {
        var baseBean = BaseBean.fromJson(data);
        if (err != null){
          err(baseBean);
        }else{
          showCenterToast(errTransformTip(baseBean.code));
        }
      }
    },err: err,done:done,isDialog: isDialog);
  }

  void onAsyncNetWork(
      {required Future future,
        required RequestResult result,
        RequestResultErr? err,
        RequestDone? done,
        bool isDialog = true}) async {
    if (isDialog) LoadDialog.showLoadDialog();
    var asStream = future.asStream();
    var listen = asStream.listen((event) {
      // print("listen ${event.toString()}");
      if(event is Response<dynamic>){
        result((event).data);
      }else {
        result(event);
      }
      notifyListeners();
    }, onError: (e, stacktrace) {
      if (e is DioError) {
        // 网络请求
        // print(
        //     "onError  ${e.response?.statusCode.toString()}  ${e.response?.statusMessage.toString()}");
        var code = e.response?.statusCode ?? ApiConfig.REQUEST_FAILED_CODE_30000;
        if (err != null) {
          err(BaseDataBean(code: code, message: errTransformTip(code)));
        }else{
          showCenterToast(errTransformTip(code));
        }
      } else {
        print("onError ${e}  ${stacktrace}");
        if (err != null){
          err(BaseDataBean(code: -2, message: e.toString()));
        }else{
          // Fluttertoast.showToast(msg:errTransformTip(-2));
        }
      }
      notifyListeners();
    }, cancelOnError: false);
    listen.onDone(() {
      if (isDialog) LoadDialog.cancelLoadDialog();
      if (done != null) done();
      removeSubscription(listen);
    });
    addSubscription(listen);
  }

  ///判断网络请求是否是200
  static bool judgeResultCode(Map<String, dynamic> result) {
    int code = result['code'];
    return code == ApiConfig.REQUEST_SUCCESS_CODE;
  }

  ///判断网络请求是否是200
  static bool judgeResultCodeAndData(Map<String, dynamic> result) {
    int code = result['code'];
    var data = result['data'];
    return code == ApiConfig.REQUEST_SUCCESS_CODE && data !=null;
  }

  // 对应错误转为响应提示
  String errTransformTip(int? code) {
    var tip;
    switch (code) {
      case ApiConfig.REQUEST_FAILED_CODE_401:
        tip = "用户信息已过期，请重新登录";
        break;
      case ApiConfig.REQUEST_FAILED_CODE_403:
        tip = "没有相关权限";
        break;
      case ApiConfig.REQUEST_FAILED_CODE_404:
      case ApiConfig.REQUEST_FAILED_CODE_500:
        tip = "服务器内部错误";
        break;
      case ApiConfig.REQUEST_FAILED_CODE_512:
        tip = "参数检验失败";
        break;
      case ApiConfig.REQUEST_FAILED_CODE_701:
      case ApiConfig.REQUEST_FAILED_CODE_702:
        tip = "支付异常，请稍后重试~";
        break;
      case ApiConfig.REQUEST_FAILED_CODE_406:
      case ApiConfig.REQUEST_FAILED_CODE_510:
        tip = "数据异常，请稍后重试~";
        break;
      default:
        tip = "出现了奇怪问题呢~ 请稍后重试~";
        break;
    }
    return tip;
  }
}
